mod read_general_json;
mod write_to_file;

pub use read_general_json::read_general_json;
pub use write_to_file::write_to_file;

use serde::de::DeserializeOwned;
use std::path::{Path, PathBuf};

pub fn join_paths(part1: &Path, part2: &Path) -> PathBuf {
    let mut path = PathBuf::from(part1);
    path.push(part2);
    path
}

pub fn deserialize_json<T: DeserializeOwned>(content: &str) -> Result<T, serde_json::Error> {
    serde_json::from_str(content)
}

pub fn deserialize_toml<T: DeserializeOwned>(content: &str) -> Result<T, toml::de::Error> {
    toml::from_str(content)
}

#[cfg(test)]
mod test_json {
    use super::deserialize_json;
    use serde::Deserialize;
    use serde_json::Error;

    #[derive(Deserialize, Debug, PartialEq)]
    struct Person {
        name: String,
        age: u32,
    }

    #[test]
    fn test_deserialize_json_success() -> Result<(), Error> {
        let json = r#"{"name": "John", "age": 30}"#;
        let person: Person = deserialize_json(json)?;
        assert_eq!(
            person,
            Person {
                name: "John".to_string(),
                age: 30
            }
        );
        Ok(())
    }

    #[test]
    fn test_deserialize_json_failure() {
        let json = r#"{"name": "John", "age": "thirty"}"#; // Invalid age
        let result: Result<Person, Error> = deserialize_json(json);
        assert!(result.is_err());
    }
}

#[cfg(test)]
mod test_toml {

    use super::deserialize_json;
    use super::deserialize_toml;
    use serde::Deserialize;
    use toml::de::Error;

    #[derive(Deserialize, Debug, PartialEq)]
    struct Config {
        title: String,
        owner: Owner,
    }

    #[derive(Deserialize, Debug, PartialEq)]
    struct Owner {
        name: String,
        dob: String, // Date of Birth as a string for simplicity
    }

    #[test]
    fn test_deserialize_toml_success() -> Result<(), Error> {
        let toml = r#"
        title = "TOML Example"
 
        [owner]
        name = "Tom Preston-Werner"
        dob = "1979-05-27T07:32:00Z" # Date of Birth
        "#;
        let config: Config = deserialize_toml(toml)?;
        assert_eq!(
            config,
            Config {
                title: "TOML Example".to_string(),
                owner: Owner {
                    name: "Tom Preston-Werner".to_string(),
                    dob: "1979-05-27T07:32:00Z".to_string(),
                },
            }
        );
        Ok(())
    }
}
